package com.example.service.webhook.business.security.service;


import com.example.service.webhook.business.security.api.SecurityClient;
import com.example.service.webhook.business.security.billitem.SecurityTask;
import com.example.service.webhook.business.security.dto.*;
import com.example.service.webhook.business.security.entity.InsuranceEntity;
import com.example.service.webhook.business.security.entity.InsuranceRecordEntity;
import com.example.service.webhook.business.security.entity.MedicalInsuranceRecordEntity;
import com.example.service.webhook.business.security.entity.UserInfoEntity;
import com.example.service.webhook.business.security.repository.InsuranceRecordRepository;
import com.example.service.webhook.business.security.repository.InsuranceRepository;
import com.example.service.webhook.business.security.repository.MedicalInsuranceRecordRepository;
import com.example.service.webhook.business.security.repository.SecurityUserInfoRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class SecurityService {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(SecurityService.class);
	
	
	@Autowired
	private ThreadPoolTaskExecutor taskExecutor;
	@Autowired
	private SecurityClient securityClient;
	@Autowired
	private SecurityUserInfoRepository securityUserInfoRepository;
	@Autowired
	private InsuranceRepository insuranceRepository;
	@Autowired
	private InsuranceRecordRepository insuranceRecordRepository;
	@Autowired
	private MedicalInsuranceRecordRepository medicalInsuranceRecordRepository;

	/**
	 *
	 * fetchBill:处理社保信息 <br/>
	 * 在收到魔蝎的社保账单回调时执行<br/>
	 * 社保信息<br/>
	 *
	 * @author vivicat
	 * @param task
	 * @since JDK 1.6
	 */
	public void fetchBill(final SecurityTask task) {
		// 这里交给线程池处理，防止下面的业务处理时间太长，导致超时。
		// 超时会导致魔蝎数据进行重试，会收到重复的回调请求
		taskExecutor.execute(
				new Runnable() {
					@Override
					public void run() {

						LOGGER.info("start fetch security bill,taskId="+task.getTaskId());
						try {
							SecurityDetails securityDetails = securityClient.getSecurity(task.getTaskId());
							if(securityDetails!=null){
								saveUserInfo(securityDetails.getUserInfo(),task);
								saveInsurances(securityDetails.getInsurances(),task,securityDetails.getUserInfo().getUserInfoId());
								saveInsuranceRecords(securityDetails.getInsuranceRecords(),task,securityDetails.getUserInfo().getUserInfoId());
								saveMedicalInsuranceRecords(securityDetails.getMedicalInsuranceRecords(),task,securityDetails.getUserInfo().getUserInfoId());
							}
						} catch (Exception e) {
							LOGGER.error("fetchBill failed. taskId:{}", task.getTaskId(), e);
						}
						LOGGER.info("end fetch security bill,taskId="+task.getTaskId());
					}
				}

		);
	}


	/**
	 * 用户基本信息
	 * saveUserInfo: 处理用户基本信息 <br/>
	 * @author vivicat
	 * @param userInfo
	 * @param task
	 * @since JDK 1.6
	 */
	private void saveUserInfo(UserInfo userInfo,SecurityTask task){
		if(userInfo!=null){
			try {
				UserInfoEntity existEntity = securityUserInfoRepository.getUserInfo(task.getUserId(), userInfo.getUserInfoId());

				UserInfoEntity userInfoEntity = new UserInfoEntity();
				BeanUtils.copyProperties(userInfo, userInfoEntity);
				userInfoEntity.setAreaCode(task.getAreaCode());
				userInfoEntity.setUserId(task.getUserId());
				if(existEntity==null){
					securityUserInfoRepository.saveUserInfoEntity(userInfoEntity);
				}else{
					userInfoEntity.setId(existEntity.getId());
					userInfoEntity.setCreateTime(existEntity.getCreateTime());
					securityUserInfoRepository.updateUserInfoEntity(userInfoEntity);
				}
			} catch (Exception e) {
				LOGGER.error("社保用户基本信息处理失败",e);
			}
		}
	}

	/**
	 *  保存险种记录
	 * saveBillRecord:保存险种记录 <br/>
	 * @author vivicat
	 * @param insurances
	 * @param task
	 * @since JDK 1.6
	 */
	private void saveInsurances(List<Insurance> insurances,SecurityTask task,String userInfoId){
		try{
			if(insurances!=null){
				insuranceRepository.deleteInsuranceEntity(task.getUserId(), userInfoId);
				for(Insurance insurance:insurances){
					InsuranceEntity insuranceEntity = new InsuranceEntity();
					BeanUtils.copyProperties(insurance, insuranceEntity);
					insuranceEntity.setUserId(task.getUserId());
					insuranceEntity.setUserInfoId(userInfoId);
					insuranceEntity.setAreaCode(task.getAreaCode());
					insuranceRepository.saveInsuranceEntity(insuranceEntity);
				}
			}
		}catch(Exception e){
			LOGGER.error("社保用户险种记录处理失败",e);
		}

	}



	/**
	 *  保存保险缴存记录信息
	 * saveLoanInfo:保存保险缴存记录信息 <br/>
	 * @author vivicat
	 * @param insuranceRecords
	 * @param task
	 * @since JDK 1.6
	 */
	private void saveInsuranceRecords(List<InsuranceRecord> insuranceRecords,SecurityTask task,String userInfoId){
		try{
			if(insuranceRecords!=null){
				insuranceRecordRepository.deleteInsuranceRecordEntity(task.getUserId(), userInfoId);
				List<InsuranceRecordEntity> insuranceRecordCalls = new ArrayList<>();

				for(InsuranceRecord insuranceRecord:insuranceRecords){

					InsuranceRecordEntity insuranceRecordEntity = new InsuranceRecordEntity();
					BeanUtils.copyProperties(insuranceRecord, insuranceRecordEntity);
					insuranceRecordEntity.setUserId(task.getUserId());
					insuranceRecordEntity.setUserInfoId(userInfoId);
					insuranceRecordEntity.setAreaCode(task.getAreaCode());
					insuranceRecordCalls.add(insuranceRecordEntity);
				}
				insuranceRecordRepository.batchSave(task.getUserId(), insuranceRecordCalls);
			}
		}catch(Exception e){
			LOGGER.error("社保用户保险缴存记录信息处理失败",e);
		}

	}


	/**
	 *  保存医保卡消费记录
	 * saveLoanInfo:保存医保卡消费记录信息 <br/>
	 * @author vivicat
	 * @param medicalInsuranceRecords
	 * @param task
	 * @since JDK 1.6
	 */
	private void saveMedicalInsuranceRecords(List<MedicalInsuranceRecord> medicalInsuranceRecords,SecurityTask task,String userInfoId){
		try{
			if(medicalInsuranceRecords!=null){
				medicalInsuranceRecordRepository.deleteMedicalInsuranceRecordEntity(task.getUserId(), userInfoId);
				for(MedicalInsuranceRecord medicalInsuranceRecord:medicalInsuranceRecords){
					MedicalInsuranceRecordEntity medicalInsuranceRecordEntity = new MedicalInsuranceRecordEntity();
					BeanUtils.copyProperties(medicalInsuranceRecord, medicalInsuranceRecordEntity);
					medicalInsuranceRecordEntity.setUserId(task.getUserId());
					medicalInsuranceRecordEntity.setUserInfoId(userInfoId);
					medicalInsuranceRecordEntity.setAreaCode(task.getAreaCode());
					medicalInsuranceRecordRepository.saveMedicalInsuranceRecordEntity(medicalInsuranceRecordEntity);
				}
			}
		}catch(Exception e){
			LOGGER.error("医保卡消费记录处理失败",e);
		}

	}
}
  
